package com.xucia.jsponic.data;

import org.mozilla.javascript.BaseFunction;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.NativeObject;
import org.mozilla.javascript.ScriptRuntime;
import org.mozilla.javascript.Scriptable;

/**
 * Implementation of <a href="http://www.persistentjavascript.org">Persistent JavaScript</a> API for Rhino 
 * 
 * @author Kris Zyp
 */
public class PjsLibrary extends NativeObject {
	public String getClassName() {
		return "Pjs";
	}
	public PjsLibrary() {
		super();
		put("load", this, new BaseFunction() {
			@Override
			public Object call(Context cx, Scriptable scope,
					Scriptable thisObj, Object[] args) {
				Object object = Identification.idForString((String) args[0]).getTarget();
				if (args.length > 1) {// call the callback if necessary
					((Function)args[1]).call(cx, scope, thisObj, new Object[]{object});
				}
				return object;
			}
			
		});
		put("get", this, new BaseFunction() {
			@Override
			public Object call(Context cx, Scriptable scope,
					Scriptable thisObj, Object[] args) {
				Object value = ScriptRuntime.getObjectElem(args[0], args[1], cx);
				if (args.length > 2) {// call the callback if necessary
					((Function)args[2]).call(cx, scope, thisObj, new Object[]{value});
				}
				return value;
			}
		});
		put("set", this, new BaseFunction() {
			@Override
			public Object call(Context cx, Scriptable scope,
					Scriptable thisObj, Object[] args) {
				((Persistable)args[0]).set((String)args[1], args[2]);
				return args[2];
			}
		});
		put("commit", this, new BaseFunction() {
			@Override
			public Object call(Context cx, Scriptable scope,
					Scriptable thisObj, Object[] args) {
				// TODO: Need to do this when we have real transactions
				return null;
			}
		});
		put("rollback", this, new BaseFunction() {
			@Override
			public Object call(Context cx, Scriptable scope,
					Scriptable thisObj, Object[] args) {
				// TODO: Need to do this when we have real transactions
				return null;
			}
		});
		put("changing", this, new BaseFunction() {
			@Override
			public Object call(Context cx, Scriptable scope,
					Scriptable thisObj, Object[] args) {
				// TODO: Need to do this when we have real transactions
				return null;
			}
		});
		put("save", this, new BaseFunction() {
			@Override
			public Object call(Context cx, Scriptable scope,
					Scriptable thisObj, Object[] args) {
				// TODO: Need to do this when we have real transactions
				return null;
			}
		});
		put("getAccessLevel", this, new BaseFunction() {
			@Override
			public Object call(Context cx, Scriptable scope,
					Scriptable thisObj, Object[] args) {
				return ((Persistable)args[0]).getAccessLevel();
			}
		});
		put("getId", this, new BaseFunction() {
			@Override
			public Object call(Context cx, Scriptable scope,
					Scriptable thisObj, Object[] args) {
				return ((Persistable)args[0]).getId().toString();
			}
		});
		put("isPersisted", this, new BaseFunction() {
			@Override
			public Object call(Context cx, Scriptable scope,
					Scriptable thisObj, Object[] args) {
				return ((Persistable)args[0]).getId().isPersisted();
			}
		});
	}
}
